package cn.topcodes.tcsf.codegen.ui;

import cn.topcodes.tcsf.codegen.domain.entity.Entity;
import cn.topcodes.tcsf.codegen.domain.entity.Field;
import cn.topcodes.tcsf.codegen.domain.entity.Program;
import cn.topcodes.tcsf.codegen.utils.CodegenUtil;
import cn.topcodes.tcsf.codegen.utils.JdbcUtil;
import cn.topcodes.tcsf.codegen.utils.NameUtil;
import cn.topcodes.tcsf.codegen.utils.ScreenUtil;
import cn.topcodes.tcsf.codegen.utils.SqliteOpenHelper;
import com.mysql.jdbc.StringUtils;
import freemarker.template.TemplateException;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

/**
 *
 * @author Unicorn
 */
public class MainFrame extends javax.swing.JFrame {
    
    private Integer entityId;
    
    private Program program;
    
    private static MainFrame instance = null;
    
    public static boolean isInit() {
        return instance != null;
    }
    
    public static MainFrame getInstance() {
        if(instance == null) {
            instance = new MainFrame();
            instance.setVisible(true);
        }
        return instance;
    }

    private MainFrame() {
        ImageIcon imageIcon = new ImageIcon("resource/images/logo.png");  
        this.setIconImage(imageIcon.getImage());  
        
        initComponents();
        ScreenUtil.initLocation(this);

        openProgramDialog();
    }

    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jScrollPane1 = new javax.swing.JScrollPane();
        treeTable = new javax.swing.JTree();
        jScrollPane2 = new javax.swing.JScrollPane();
        listTable = new javax.swing.JList();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        btnAdd = new javax.swing.JButton();
        btnRemove = new javax.swing.JButton();
        jPanel1 = new javax.swing.JPanel();
        txtGenMapper = new javax.swing.JTextField();
        txtDisplayName = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        txtGenController = new javax.swing.JTextField();
        jLabel1 = new javax.swing.JLabel();
        txtEntityClass = new javax.swing.JTextField();
        txtGenService = new javax.swing.JTextField();
        jLabel4 = new javax.swing.JLabel();
        lblCurrentTable = new javax.swing.JLabel();
        btnSetField = new javax.swing.JButton();
        btnSave = new javax.swing.JButton();
        txtControllerUrl = new javax.swing.JTextField();
        lblControllerUrl = new javax.swing.JLabel();
        jLabel5 = new javax.swing.JLabel();
        txtPageFolder = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        txtVoClass = new javax.swing.JTextField();
        jLabel8 = new javax.swing.JLabel();
        txtFormClass = new javax.swing.JTextField();
        jLabel9 = new javax.swing.JLabel();
        txtForm2EntityConvertorClass = new javax.swing.JTextField();
        jLabel10 = new javax.swing.JLabel();
        txtEntity2VoConvertorClass = new javax.swing.JTextField();
        jLabel11 = new javax.swing.JLabel();
        jLabel12 = new javax.swing.JLabel();
        jLabel13 = new javax.swing.JLabel();
        btnGenCode = new javax.swing.JButton();
        jMenuBar1 = new javax.swing.JMenuBar();
        menuProgramManage = new javax.swing.JMenu();
        menuAbout = new javax.swing.JMenu();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("代码生成器");
        setResizable(false);

        javax.swing.tree.DefaultMutableTreeNode treeNode1 = new javax.swing.tree.DefaultMutableTreeNode("请选择项目");
        treeTable.setModel(new javax.swing.tree.DefaultTreeModel(treeNode1));
        jScrollPane1.setViewportView(treeTable);

        listTable.setModel(new DefaultListModel());
        jScrollPane2.setViewportView(listTable);
        listTable.addListSelectionListener(new TableListSelectionListener());

        jLabel2.setText("数据表");

        jLabel3.setText("本次生成");

        btnAdd.setText("添加 >>");
        btnAdd.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnAddMousePressed(evt);
            }
        });

        btnRemove.setText("<< 移除");
        btnRemove.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnRemoveMousePressed(evt);
            }
        });

        txtGenMapper.setEnabled(false);

        txtDisplayName.setColumns(10);
        txtDisplayName.setAutoscrolls(false);
        txtDisplayName.setEnabled(false);
        txtDisplayName.setMaximumSize(new java.awt.Dimension(30, 200));
        txtDisplayName.setMinimumSize(new java.awt.Dimension(30, 200));

        jLabel6.setText("显示名称：");

        txtGenController.setEnabled(false);

        jLabel1.setText("实体类名：");

        txtEntityClass.setEnabled(false);

        txtGenService.setEnabled(false);

        jLabel4.setText("当前编辑：");

        lblCurrentTable.setText("无");

        btnSetField.setText("字段设置");
        btnSetField.setEnabled(false);
        btnSetField.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                btnSetFieldMousePressed(evt);
            }
        });

        btnSave.setText("保存修改");
        btnSave.setEnabled(false);
        btnSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnSaveActionPerformed(evt);
            }
        });

        txtControllerUrl.setEnabled(false);

        lblControllerUrl.setText("控制器URL：");

        jLabel5.setText("页面存放路径：");

        txtPageFolder.setEnabled(false);

        jLabel7.setText("VO类名：");

        txtVoClass.setEnabled(false);

        jLabel8.setText("Form类名：");

        txtFormClass.setEnabled(false);

        jLabel9.setText("Form转换类名：");

        txtForm2EntityConvertorClass.setEnabled(false);

        jLabel10.setText("VO转换类名：");

        txtEntity2VoConvertorClass.setEnabled(false);

        jLabel11.setText("Mapper类名：");

        jLabel12.setText("Service类名：");

        jLabel13.setText("控制器类名：");

        btnGenCode.setText("生成代码");
        btnGenCode.setEnabled(false);
        btnGenCode.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnGenCodeActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel9, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(lblControllerUrl, javax.swing.GroupLayout.DEFAULT_SIZE, 118, Short.MAX_VALUE)
                            .addComponent(jLabel5, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel8, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addComponent(jLabel11, javax.swing.GroupLayout.PREFERRED_SIZE, 102, javax.swing.GroupLayout.PREFERRED_SIZE)
                                    .addComponent(jLabel12)
                                    .addComponent(jLabel13))
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)))
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                                .addComponent(txtGenMapper, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                                .addComponent(txtGenService, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                                .addComponent(txtGenController, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                                .addComponent(txtControllerUrl, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                                .addComponent(txtPageFolder, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                                .addComponent(txtForm2EntityConvertorClass)
                                .addComponent(txtFormClass)
                                .addComponent(txtEntity2VoConvertorClass))
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(btnSetField)
                                .addGap(18, 18, 18)
                                .addComponent(btnSave)
                                .addGap(18, 18, 18)
                                .addComponent(btnGenCode, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE))))
                    .addComponent(jLabel6, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGap(118, 118, 118)
                        .addComponent(lblCurrentTable, javax.swing.GroupLayout.PREFERRED_SIZE, 430, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(jPanel1Layout.createSequentialGroup()
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(jLabel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addGroup(jPanel1Layout.createSequentialGroup()
                                .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, 113, Short.MAX_VALUE)
                                .addGap(5, 5, 5))
                            .addComponent(jLabel7, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addComponent(txtVoClass)
                            .addComponent(txtEntityClass, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE)
                            .addComponent(txtDisplayName, javax.swing.GroupLayout.DEFAULT_SIZE, 430, Short.MAX_VALUE))))
                .addContainerGap(14, Short.MAX_VALUE))
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {lblCurrentTable, txtControllerUrl, txtDisplayName, txtEntityClass, txtGenController, txtGenMapper, txtGenService, txtPageFolder, txtVoClass});

        jPanel1Layout.setVerticalGroup(
            jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup()
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel4)
                    .addComponent(lblCurrentTable))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel6)
                    .addComponent(txtDisplayName, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel1)
                    .addComponent(txtEntityClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel7)
                    .addComponent(txtVoClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(txtEntity2VoConvertorClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel10))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel8)
                    .addComponent(txtFormClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel9)
                    .addComponent(txtForm2EntityConvertorClass, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtGenMapper, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel11))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtGenService, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel12))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(txtGenController)
                    .addComponent(jLabel13, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(txtControllerUrl, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(lblControllerUrl))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(txtPageFolder, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addGroup(jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(btnSetField)
                    .addComponent(btnSave)
                    .addComponent(btnGenCode))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel10, jLabel11, jLabel8, jLabel9, txtEntity2VoConvertorClass, txtForm2EntityConvertorClass, txtFormClass, txtGenMapper});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel13, jLabel5, lblControllerUrl, txtControllerUrl, txtGenController, txtPageFolder});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel4, jLabel6, lblCurrentTable, txtDisplayName});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel1, txtEntityClass});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel7, txtVoClass});

        jPanel1Layout.linkSize(javax.swing.SwingConstants.VERTICAL, new java.awt.Component[] {jLabel12, txtGenService});

        menuProgramManage.setText("项目");
        menuProgramManage.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                menuProgramManageMousePressed(evt);
            }
        });
        jMenuBar1.add(menuProgramManage);

        menuAbout.setText("关于");
        menuAbout.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mousePressed(java.awt.event.MouseEvent evt) {
                menuAboutMousePressed(evt);
            }
        });
        jMenuBar1.add(menuAbout);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 235, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                            .addComponent(btnAdd)
                            .addComponent(btnRemove))))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(jLabel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 220, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(18, 18, 18)
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addComponent(jLabel2)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE))))
            .addGroup(layout.createSequentialGroup()
                .addComponent(jLabel3)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jScrollPane2))
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                        .addComponent(btnAdd)
                        .addGap(52, 52, 52)
                        .addComponent(btnRemove)
                        .addGap(230, 230, 230))))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void menuProgramManageMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_menuProgramManageMousePressed
        openProgramDialog();
    }//GEN-LAST:event_menuProgramManageMousePressed

    private void openProgramDialog() {
        ProgramDialog dialog = new ProgramDialog(this,true);
        dialog.setVisible(true);
    }
    
    private void btnAddMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnAddMousePressed
        DefaultMutableTreeNode node = (DefaultMutableTreeNode) treeTable.getLastSelectedPathComponent();
        if(node == null || node.isRoot()) {
            return;
        }
        String table = node.toString();
        DefaultListModel model = (DefaultListModel)this.listTable.getModel();
        if(!model.contains(table)) {
            try {
                Entity entity = new Entity();
                entity.setProgram(this.program);
                entity.setTableName(table);
                //  去除前缀
                String newTableName = table;
                if(!StringUtils.isNullOrEmpty(this.program.getPrefix())) {
                    String[] prefixs = this.program.getPrefix().split(",");
                    if(prefixs != null) {
                        for(String prefix : prefixs) {
                            newTableName = newTableName.replace(prefix, "");
                        }
                    }
                }
                String pascalTable = NameUtil.underline2Pascal(newTableName);
                entity.setEntityClass(program.getPackageName() + ".domain.entity." + pascalTable);
                String remark = JdbcUtil.getTableRemark(program.getDbType(), program.getIp(), program.getPort(),
                    program.getUsername(), program.getPassword(), program.getDbName(), table);
                if(StringUtils.isNullOrEmpty(remark)) {
                    entity.setDisplayName(pascalTable);
                }else {
                    entity.setDisplayName(remark);
                }
                entity.setMapperClass(program.getPackageName() + ".mapper." + pascalTable + "Mapper");
                entity.setServiceClass(program.getPackageName() + ".service." + pascalTable + "Service");
                entity.setControllerClass(program.getPackageName() + ".web.controller." + pascalTable + "Controller");
                entity.setControllerUrl("/admin/" + pascalTable.toLowerCase());
                entity.setPageFolder(pascalTable.toLowerCase());
                entity.setVoClass(program.getPackageName() + ".domain.vo." + pascalTable + "Vo");
                entity.setFormClass(program.getPackageName() + ".domain.form." + pascalTable + "Form");
                entity.setEntity2VoConvertorClass(program.getPackageName() + ".convertor." + pascalTable + "Entity2VoConvertor");
                entity.setForm2EntityConvertorClass(program.getPackageName() + ".convertor." + pascalTable + "Form2EntityConvertor");
                SqliteOpenHelper.getEntityDao().create(entity);
                List<Field> fields = JdbcUtil.getFields(program.getDbType(), 
                        program.getIp(), program.getPort(), program.getUsername(), program.getPassword(),
                        program.getDbName(), table);
                for(Field field : fields) {
                    field.setEntity(entity);
                }
                SqliteOpenHelper.getFieldDao().create(fields);
                model.addElement(table);
            }catch(Exception e) {
                e.printStackTrace();
                JOptionPane.showMessageDialog(this, "添加失败:" + e.getMessage());
            }
        }
        
        if(model.getSize() > 0) {
            this.btnGenCode.setEnabled(true);
        }else {
            this.btnGenCode.setEnabled(false);
        }
    }//GEN-LAST:event_btnAddMousePressed

    private void btnRemoveMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnRemoveMousePressed
        int index = this.listTable.getLeadSelectionIndex();
        if(index < 0) {
            return;
        }
        DefaultListModel model = (DefaultListModel) this.listTable.getModel();
        if(index >= model.size()) {
            return;
        }
        try {
            String table = model.elementAt(index).toString();
            List<Entity> entitys = SqliteOpenHelper.getEntityDao().queryForEq("table_name", table);
            for(Entity entity : entitys) {
                SqliteOpenHelper.getFieldDao().delete(entity.getFields());
            }
            SqliteOpenHelper.getEntityDao().delete(entitys);
            model.remove(index);
        }catch(Exception e) {
            JOptionPane.showMessageDialog(this, "移除失败");
        }
        clearForm();
        
        if(model.getSize() > 0) {
            this.btnGenCode.setEnabled(true);
        }else {
            this.btnGenCode.setEnabled(false);
        }
    }//GEN-LAST:event_btnRemoveMousePressed

    private void btnGenCodeActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnGenCodeActionPerformed
        //  生成代码前注意保存修改
        saveEntity();
        
        if(this.program != null) {
            try {
                CodegenUtil.genCode(this.program);
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(this, "生成失败！发生读写异常");
            } catch (TemplateException ex) {
                JOptionPane.showMessageDialog(this, "生成失败！请检查代码模板是否正确");
            }
        }
        JOptionPane.showMessageDialog(this, "生成成功!");
    }//GEN-LAST:event_btnGenCodeActionPerformed

    private void btnSetFieldMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_btnSetFieldMousePressed
        SetFieldDialog dialog = new SetFieldDialog(this,true,entityId);
        dialog.setVisible(true);
    }//GEN-LAST:event_btnSetFieldMousePressed

    private void btnSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnSaveActionPerformed
        saveEntity();
    }//GEN-LAST:event_btnSaveActionPerformed

    private void menuAboutMousePressed(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_menuAboutMousePressed
        AboutDialog aboutDialog = new AboutDialog(this,true);
        aboutDialog.setVisible(true);
    }//GEN-LAST:event_menuAboutMousePressed

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnAdd;
    private javax.swing.JButton btnGenCode;
    private javax.swing.JButton btnRemove;
    private javax.swing.JButton btnSave;
    private javax.swing.JButton btnSetField;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JScrollPane jScrollPane2;
    private javax.swing.JLabel lblControllerUrl;
    private javax.swing.JLabel lblCurrentTable;
    private javax.swing.JList listTable;
    private javax.swing.JMenu menuAbout;
    private javax.swing.JMenu menuProgramManage;
    private javax.swing.JTree treeTable;
    private javax.swing.JTextField txtControllerUrl;
    private javax.swing.JTextField txtDisplayName;
    private javax.swing.JTextField txtEntity2VoConvertorClass;
    private javax.swing.JTextField txtEntityClass;
    private javax.swing.JTextField txtForm2EntityConvertorClass;
    private javax.swing.JTextField txtFormClass;
    private javax.swing.JTextField txtGenController;
    private javax.swing.JTextField txtGenMapper;
    private javax.swing.JTextField txtGenService;
    private javax.swing.JTextField txtPageFolder;
    private javax.swing.JTextField txtVoClass;
    // End of variables declaration//GEN-END:variables

    public void design(Program program) {
        //  切换项目前注意保存修改
        saveEntity();
        
        this.clear();
        List<String> tables = JdbcUtil.getTables(program.getDbType(), 
                program.getIp(), program.getPort(), program.getUsername(),
                program.getPassword(), program.getDbName());
        
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(program.getDbName());    
        for(String table : tables) {
            DefaultMutableTreeNode child = new DefaultMutableTreeNode(table);  
            root.add(child);
        }
        DefaultTreeModel model = (DefaultTreeModel) this.treeTable.getModel();
        model.setRoot(root);
        this.treeTable.updateUI();
        Collection<Entity> entitys = program.getEntitys();
        List<String> tableNames = new ArrayList<String>();
        for(Entity entity : entitys) {
            tableNames.add(entity.getTableName());
        }
        DefaultListModel dlm = (DefaultListModel) this.listTable.getModel();
        for(String tableName : tableNames) {
            dlm.addElement(tableName);
        }
        this.setTitle("代码生成器 - " + program.getName());
        this.program = program;
        
        if(dlm.getSize() > 0) {
            this.btnGenCode.setEnabled(true);
        }else {
            this.btnGenCode.setEnabled(false);
        }
    }
    
    class TableListSelectionListener implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {
            //  切换实体前注意保存修改
            saveEntity();
            
            try {
                DefaultListModel model = (DefaultListModel) MainFrame.this.listTable.getModel();
                if(model.isEmpty()) {
                    return;
                }
                int index = MainFrame.this.listTable.getLeadSelectionIndex();
                if(index >= model.size()) {
                    return;
                }
                String table = model.elementAt(index).toString();
                List<Entity> entitys = SqliteOpenHelper.getEntityDao().queryForEq("table_name", table);
                if(entitys.isEmpty()) {
                    return;
                }
                Entity entity = entitys.get(0);
                MainFrame.this.lblCurrentTable.setText(table);
                MainFrame.this.txtDisplayName.setText(entity.getDisplayName());
                MainFrame.this.txtDisplayName.setEnabled(true);
                MainFrame.this.txtEntityClass.setText(entity.getEntityClass());
                MainFrame.this.txtEntityClass.setEnabled(true);
                MainFrame.this.txtVoClass.setText(entity.getVoClass());
                MainFrame.this.txtFormClass.setText(entity.getFormClass());
                MainFrame.this.txtEntity2VoConvertorClass.setText(entity.getEntity2VoConvertorClass());
                MainFrame.this.txtForm2EntityConvertorClass.setText(entity.getForm2EntityConvertorClass());
                MainFrame.this.txtVoClass.setEnabled(true);
                MainFrame.this.txtFormClass.setEnabled(true);
                MainFrame.this.txtEntity2VoConvertorClass.setEnabled(true);
                MainFrame.this.txtForm2EntityConvertorClass.setEnabled(true);
                
                MainFrame.this.txtGenMapper.setEnabled(true);
                MainFrame.this.txtGenMapper.setText(entity.getMapperClass());
                
                MainFrame.this.txtGenService.setEnabled(true);
                MainFrame.this.txtGenService.setText(entity.getServiceClass());
                
                MainFrame.this.txtGenController.setEnabled(true);
                MainFrame.this.txtGenController.setText(entity.getControllerClass());
                MainFrame.this.txtControllerUrl.setEnabled(true);
                MainFrame.this.txtControllerUrl.setText(entity.getControllerUrl());
                MainFrame.this.txtPageFolder.setText(entity.getPageFolder());
                MainFrame.this.txtPageFolder.setEnabled(true);
                
                
                MainFrame.this.btnGenCode.setEnabled(true);
                MainFrame.this.btnSetField.setEnabled(true);
                
                MainFrame.this.entityId = entity.getId();
                
                MainFrame.this.btnSave.setEnabled(true);
            } catch (SQLException ex) {
                Logger.getLogger(MainFrame.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
    }

    public int getProgramId() {
        return program != null ? program.getId() : -1;
    }
    
    public void clear() {
        //  清除前注意保存修改
        saveEntity();
        
        DefaultTreeModel treeModel = (DefaultTreeModel)this.treeTable.getModel();
        DefaultMutableTreeNode root = new DefaultMutableTreeNode("请选择项目");
        treeModel.setRoot(root);
        this.treeTable.updateUI();
        DefaultListModel dlm = (DefaultListModel) this.listTable.getModel();
        dlm.clear();
        
        this.program = null;
        
        this.setTitle("代码生成器");
        
        clearForm();
    }

    public void clearForm() {
        this.entityId = null;
        
        this.lblCurrentTable.setText("");
        this.lblCurrentTable.setEnabled(false);
        this.txtDisplayName.setText("");
        this.txtDisplayName.setEnabled(false);
        this.txtEntityClass.setText("");
        this.txtEntityClass.setEnabled(false);
        this.txtVoClass.setText("");
        this.txtFormClass.setText("");
        this.txtEntity2VoConvertorClass.setText("");
        this.txtForm2EntityConvertorClass.setText("");
        this.txtVoClass.setEnabled(false);
        this.txtFormClass.setEnabled(false);
        this.txtEntity2VoConvertorClass.setEnabled(false);
        this.txtForm2EntityConvertorClass.setEnabled(false);

        this.txtGenMapper.setEnabled(false);
        this.txtGenMapper.setText("");
        this.txtGenMapper.setEnabled(false);
        
        this.txtGenService.setEnabled(false);
        this.txtGenService.setText("");

        this.txtGenController.setEnabled(false);
        this.txtGenController.setText("");
        this.txtControllerUrl.setEnabled(false);
        this.txtControllerUrl.setText("");
        this.txtPageFolder.setEnabled(false);
        this.txtPageFolder.setText("");

        this.btnGenCode.setEnabled(false);
        this.btnSetField.setEnabled(false);
        
        MainFrame.this.btnSave.setEnabled(false);
    }
    
    private void saveEntity() {
        if(entityId == null) {
            return;
        }
        String displayName = this.txtDisplayName.getText();
        String entityName = this.txtEntityClass.getText();
        String genMapper = this.txtGenMapper.getText();
        String genService = this.txtGenService.getText();
        String genController = this.txtGenController.getText();
        String controllerUrl = this.txtControllerUrl.getText();
        String pageFolder = this.txtPageFolder.getText();
        String voName = this.txtVoClass.getText();
        String formName = this.txtFormClass.getText();
        String entity2VoConvertorName = this.txtEntity2VoConvertorClass.getText();
        String form2EntityConvertorName = this.txtForm2EntityConvertorClass.getText();
        
        Entity entity = new Entity();
        entity.setId(entityId);
        entity.setProgram(this.program);
        entity.setTableName(this.lblCurrentTable.getText());
        entity.setDisplayName(displayName);
        entity.setEntityClass(entityName);
        entity.setVoClass(voName);
        entity.setFormClass(formName);
        entity.setEntity2VoConvertorClass(entity2VoConvertorName);
        entity.setForm2EntityConvertorClass(form2EntityConvertorName);
        entity.setMapperClass(genMapper);
        entity.setServiceClass(genService);
        entity.setControllerClass(genController);
        entity.setControllerUrl(controllerUrl);
        entity.setPageFolder(pageFolder);
        try {
            SqliteOpenHelper.getEntityDao().update(entity);
        } catch (SQLException ex) {
            ex.printStackTrace();
            JOptionPane.showMessageDialog(this, "保存失败:" + ex.getMessage());
        }
    }
}
